﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using MiniFox.Configurations;
using MiniFox.Web.AppStarting;
using MiniFox.Web.Configurations;
using Swashbuckle.AspNetCore.Filters;

namespace SwaggerUI
{
    /// <summary>
    /// 
    /// </summary>
    public class SwaggerInitalizer : HttpStartBase
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="hostEnvironment"></param>
        /// <param name="webConfiguration"></param>
        public SwaggerInitalizer(IConfiguration configuration, IWebHostEnvironment hostEnvironment, WebConfiguration webConfiguration) : base(configuration, hostEnvironment, webConfiguration)
        {
        }
        /// <summary>
        /// 
        /// </summary>
        protected virtual SwaggerConfiguration SwaggerConfiguration
        {
            get
            {
                SwaggerConfiguration config = ConfigurationFactory.GetConfig<SwaggerConfiguration>();
                return config;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="app"></param>
        public override void OnApplicationConfiguring(IApplicationBuilder app)
        {
            if (!this.Environment.IsDevelopment())
                return;

            app.UseSwagger();
            app.UseSwaggerUI(options =>
            {
                options.SwaggerEndpoint($"/swagger/{SwaggerConfiguration.Version}/swagger.json", this.SwaggerConfiguration.Name);
            });
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="services"></param>
        public override void OnServicesConfiguring(IServiceCollection services)
        {
            if (!this.Environment.IsDevelopment())
                return;
            if (SwaggerConfiguration != null && !SwaggerConfiguration.DisableFetch)
            {
                try
                {
                    services.AddEndpointsApiExplorer();
                    services.AddSwaggerGen(options =>
                    {
                        //基本信息配置
                        options.SwaggerDoc(SwaggerConfiguration.Version, new OpenApiInfo
                        {
                            Version = SwaggerConfiguration.Version,
                            Title = SwaggerConfiguration.Name,
                            Description = ""
                        });

                        string basePath = @$"{AppContext.BaseDirectory.TrimEnd('\\')}\{SwaggerConfiguration.BasePath.TrimStart('\\')}";
                        if (SwaggerConfiguration.FilePathSettings != null && SwaggerConfiguration.FilePathSettings.Length > 0)
                        {
                            foreach (var path in SwaggerConfiguration.FilePathSettings)
                            {
                                options.IncludeXmlComments(@$"{basePath}\{path.TrimStart('\\')}");
                            }
                        }
                        else
                        {
                            var paths = Directory.GetFiles(basePath, "*.xml");
                            foreach (string path in paths)
                            {
                                options.IncludeXmlComments(path);
                            }
                        }
                        options.OperationFilter<SecurityRequirementsOperationFilter>();
                        options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
                        {
                            Name = "Authorization",
                            In = ParameterLocation.Header,
                            Type = SecuritySchemeType.ApiKey,
                            Description = "用于保存用户验证的passport客户端令牌（一般为oauth2.0协议的 json web token"
                        });
                    });
                }
                catch
                {
                }
            }
        }
    }

    //public class AuthHeaderFilter : IOperationFilter
    //{
    //    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    //    {
    //        var parameters = new List<OpenApiParameter>();
    //        var apiDescription = context.ApiDescription;

    //        if (!apiDescription.CustomAttributes().Contains(typeof(AllowAnonymousAttribute)))
    //        {
    //            var hasOpenAuthFilter = actionFilters.Any(f => f.Instance is ApiAuthorizationFilter);
    //            hasOpenAuthFilter |= apiDescription.ActionDescriptor.GetCustomAttributes<ApiAuthorizationFilter>().Any();
    //            hasOpenAuthFilter |= apiDescription.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<ApiAuthorizationFilter>().Any();
    //            if (hasOpenAuthFilter)
    //            {
    //                parameters.Add(new OpenApiParameter { Name = ClientKey.SECURE_CLIENT_TOKEN, In = ParameterLocation.Header, Description = "用于保存用户验证的passport客户端令牌（一般为oauth2.0协议的 json web token）", Required = true });
    //                parameters.Add(new OpenApiParameter { Name = ClientKey.SECURE_CLIENT, In = ParameterLocation.Header, Description = "用于保存用户验证的passport客户端上下文的键名", Required = false });
    //            }

    //        }

    //        var hasApiAuthFilter = actionFilters.Any(f => f.Instance is ApiAuthorizationFilter);
    //        hasApiAuthFilter |= apiDescription.ActionDescriptor.GetCustomAttributes<ApiAuthorizationFilter>().Any();
    //        hasApiAuthFilter |= apiDescription.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<ApiAuthorizationFilter>().Any();
    //        if (hasApiAuthFilter)
    //        {
    //            parameters.Add(new OpenApiParameter { Name = "Authorization", In = ParameterLocation.Header, Description = "Bear <JWT>", Required = true });
    //        }

    //        if (operation.Parameters != null)
    //        {
    //            parameters.AddRange(operation.Parameters);
    //        }
    //        operation.Parameters = parameters;
    //    }
    //}
}
